<template>
  <div style="text-align: center" v-loading="grantStatus">
    <el-table :data="grantList" style="width: 100%" v-loading="tableLoading" stripe>
      <el-table-column
        show-overflow-tooltip
        prop="channelId"
        label="频道ID">
      </el-table-column>
      <el-table-column
        show-overflow-tooltip
        prop="title"
        label="频道名">
      </el-table-column>
      <el-table-column
        show-overflow-tooltip
        prop="description"
        label="频道描述">
      </el-table-column>
      <el-table-column
        show-overflow-tooltip
        prop="updateTime"
        label="绑定时间">
      </el-table-column>
      <el-table-column label="操作" width="100px">
        <template slot-scope="scope">
          <el-button type="danger" plain size="small" @click="revokeGrant(scope.row)">移除授权</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div style="margin-top: 20px">
      <el-button type="primary" size="small" plain @click="login" :loading="grantStatus">获取授权</el-button>
      <div style="color: red">* 请确保您已开启VPN并能正常访问Google</div>
    </div>
  </div>
</template>

<script>
import {
  getGrantInfo,
  updateGrant,
  removeGrant,
  exchangeToken,
  getChannelInfo,
  revokeToken
} from "@/api/business/youtubeConfig";

export default {
  name: "youtube",
  props: {
    youtubeCode: {
      type: String,
      default: null
    }
  },
  data() {
    return {
      loginUrl: 'https://accounts.google.com/o/oauth2/v2/auth?scope={0}&access_type={1}&include_granted_scopes={2}&state={3}&redirect_uri={4}&response_type={5}&client_id={6}',
      scope: 'https://www.googleapis.com/auth/youtube',
      accessType: 'offline',
      includeGrantedScopes: true,
      state: 'state_parameter_passthrough_value',
      redirectUri: window.location.protocol + '//' + window.location.host + window.location.pathname,
      responseType: 'code',
      clientId: '434175254256-f9ldue13rpgn7c6oa5n6s6qqsr5geoge.apps.googleusercontent.com',
      clientSecret: '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',
      grantType: 'authorization_code',
      grantStatus: false,
      tableLoading: false,
      grantList: [],
      channelUrl: 'https://youtube.googleapis.com/youtube/v3/channels?part={0}&mine={1}&key={2}&access_token={3}',
      part: 'snippet,contentDetails,brandingSettings',
      mine: true,
      apiKey: 'AIzaSyDnQaprK9K4pwhbr5i7alrQ8-uxexA_xBk',
      revokeUrl: 'https://oauth2.googleapis.com/revoke?token={0}'
    }
  },
  mounted() {
    if (this.youtubeCode) {
      this.getGoogleToken()
    } else {
      this.queryGrantInfo()
    }
  },
  methods: {
    login() {
      let url = this.loginUrl.format(
        this.scope,
        this.accessType,
        this.includeGrantedScopes,
        this.state,
        this.redirectUri,
        this.responseType,
        this.clientId
      )
      window.open(url, '_self')
    },
    revokeGrant(row) {
      this.$confirm('此操作将从Google中移除Beetles对该频道的授权, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        this.removeToken(row.refreshToken).then(() => {
          removeGrant(row.id).then(() => {
            this.$message.success("移除成功！")
            this.queryGrantInfo()
          })
        }).catch(res => {
          console.log(res);
          this.$message.error("移除失败，请确认您已开启VPN并能正常访问Google！")
          this.tableLoading = false
        })
      }).catch(() => {
      })
    },
    queryGrantInfo() {
      this.tableLoading = true
      getGrantInfo().then(res => {
        this.grantList = res.data.data
      }).finally(() => {
        this.tableLoading = false
      })
    },
    getGoogleToken() {
      this.grantStatus = true
      let data = {
        code: this.youtubeCode,
        client_id: this.clientId,
        client_secret: this.clientSecret,
        redirect_uri: this.redirectUri,
        grant_type: this.grantType
      }

      exchangeToken(data, (res) => {
        console.log(res.currentTarget)
        let response = JSON.parse(res.currentTarget.response)
        if (res.currentTarget.status === 200) {
          this.getChannel(response)
        } else {
          if (response.error === 'invalid_grant' && response.error_description === 'Bad Request') {
            this.$message.error("授权码已过期！")
          } else {
            this.$message.error("获取授权失败，参考信息：" + response.error_description)
          }
          this.queryGrantInfo()
          this.grantStatus = false
        }
      }, (res) => {
        this.$message.error("连接Google不成功，获取授权失败，请确认您已开启VPN并能正常访问Google！")
        console.log(res);
        this.queryGrantInfo()
        this.grantStatus = false
      })
    },
    getChannel(response) {
      if (response['refresh_token']) {
        let url = this.channelUrl.format(this.part, this.mine, this.apiKey, response['access_token'])
        getChannelInfo(url, (res) => {
          let channelResponse = JSON.parse(res.currentTarget.response)
          if (channelResponse.items !== undefined && channelResponse.items[0] !== undefined) {
            let data = {
              'channelId': channelResponse.items[0].id,
              'title': channelResponse.items[0].snippet.title,
              'description': channelResponse.items[0].snippet.description,
              'refreshToken': response['refresh_token']
            }

            updateGrant(data).then(() => {
              this.$message.success("获取授权成功!")
              this.queryGrantInfo()
              this.grantStatus = false
            })
          } else {
            this.$message.error("获取频道失败，请确认您的Google账号已在YouTube上注册并且有频道！")
            this.queryGrantInfo()
            this.grantStatus = false
          }
        }, (res) => {
          this.$message.error("连接Google不成功，获取授权失败，请确认您已开启VPN并能正常访问Google！")
          console.log(res);
          this.queryGrantInfo()
          this.grantStatus = false
        })
      } else {
        this.$message.error("未能获取完整授权，这可能和网络有关，请您尝试重新获取授权！")
        this.removeToken(response['access_token'])
        this.queryGrantInfo()
        this.grantStatus = false
      }
    },
    removeToken(token) {
      return new Promise((resolve, reject) => {
        let url = this.revokeUrl.format(token)
        revokeToken(url, (res) => {
          resolve(res)
        }, (res) => {
          reject(res)
        })
      })
    }
  }
}

</script>

<style scoped>

</style>
